package tester;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import Comparator.BlockVolumeComparator;

import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import packing.Block;
import packing.BoxInput;
import packing.BoxPack;
import packing.Container;
import packing.EmptySpace;
import packing.EmptySpaceBlockPair;
import packing.PositionSimpleBlockPair;
import packing.Reader;
import packing.SimpleBlock;
import packing.State;
import packing.treeSearch.CLTRS;
import packing.treeSearch.Node;
import packing.treeSearch.Packer;
import packing.treeSearch.Tree;

public class tester {
	public static ObjectArrayList<State> readAllTest() {
		ObjectArrayList<State> originalState = new ObjectArrayList<State>();
		originalState.addAll(Reader.readBRSet("TestFiles\\br01.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br02.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br03.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br04.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br05.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br06.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br07.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br08.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br09.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br10.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br11.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br12.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br13.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br14.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br15.txt"));
		return originalState;
	}

	public static void main(String[] argv) {
		List<State> list = Reader.readBRSet("TestFiles\\hanuman.txt");
		long start_time = System.nanoTime();
		State state = list.get(0);

		Container c1 = new Container(state.getContainer().getWidth() / 2, state
				.getContainer().getLength() / 2, state.getContainer()
				.getHeight(), state.getContainer().getWeightLimit());
		Container c2 = new Container(state.getContainer().getWidth() / 2, state
				.getContainer().getLength() / 2, state.getContainer()
				.getHeight(), state.getContainer().getWeightLimit());
		Container c3 = new Container(state.getContainer().getWidth()
				- state.getContainer().getWidth() / 2, state.getContainer()
				.getLength() - state.getContainer().getLength() / 2, state
				.getContainer().getHeight(), state.getContainer().getWeightLimit());
		Container c4 = new Container(state.getContainer().getWidth()
				- state.getContainer().getWidth() / 2, state.getContainer()
				.getLength() - state.getContainer().getLength() / 2, state
				.getContainer().getHeight(), state.getContainer().getWeightLimit());
		
		ArrayList<Container> lc = new ArrayList<Container>();
		lc.add(c1);
		lc.add(c2);
		lc.add(c3);
		lc.add(c4);

		List<BoxInput> lb = state.getBoxInputList();
		double sumEvaluationScore = 0.0 ;
		ArrayList<Object> data = new ArrayList<Object>();
		
		for (int k = 0; k < lc.size(); k++) {
			state = new State(""+k, lc.get(k), lb);
			EmptySpace emptySpace = state.getEmptySpaceStack().peek(0);
			Packer packer = new Packer();
			List<Block> blockList = packer.getFitableBlock(state, emptySpace,
					false, 0.98);
			Collections.sort(blockList, new BlockVolumeComparator());
			CLTRS search = new CLTRS();
			Node<State> root = new Node<State>(state);
			search.extendSolution(root, 5, 11, blockList);

			Tree<State> tree = new Tree<State>(root);
			List<Node<State>> nodelist = tree.toList();

//			for (Node<State> s : treelist) {
//				s.getData().sortByPressure(true);
//			}
//			List<Node<State>> nodelist = new ArrayList<Node<State>>();

			double max = 0.0;
			String txt = "";
			State bestState = null;
			System.out
					.println("\n================================== เกิด State ขึ้นทั้งหมด  "
							+ nodelist.size()
							+ "  State ====================================");
			for (int i = 0; i < nodelist.size(); i++) {
				System.out
						.println("\n==================================State : "
								+ i + "====================================");
				State currentState = nodelist.get(i).getData();
				System.out.println(currentState.evaluate());
				// if((currentState.getEvaluationScore() > max) &&
				// (currentState.getTotalWeight() <=
				// currentState.getContainer().getWeightLimit())){
				if (currentState.getEvaluationScore() > max) {
					bestState = currentState;
					max = bestState.getEvaluationScore();
					txt = "Best State : " + i + " ( boxplaces_" + i + ".txt )";
				}
			}
			System.out
					.println("======================================================================");
			if (bestState != null) {
				sumEvaluationScore += max ;
				bestState.print2File("boxplaces_sub" + k + ".txt");
				System.out.println(txt + " :: อัตราส่วนการใช้พื้นที่ : " + max
						+ " , น้ำหนักรวม : " + bestState.getTotalWeight());

				List<PositionSimpleBlockPair> positionBlockList = new ObjectArrayList<PositionSimpleBlockPair>();
				for (EmptySpaceBlockPair emptySpaceBlockPair : bestState
						.getPackedBlockList()) {
					positionBlockList.add(emptySpaceBlockPair
							.getPairMainBlock());
					if (!emptySpaceBlockPair.getBlock().isSimpleBlock())
						positionBlockList.add(emptySpaceBlockPair
								.getPairNextBlock());

				}
				for (PositionSimpleBlockPair positionBlockPair : positionBlockList) {
					SimpleBlock simpleBlock = positionBlockPair
							.getSimpleblock();
					BoxPack b = simpleBlock.getBox();
					for (int i = 0; i < state.getBoxInputList().size(); i++) {
						if (b.getId() == state.getBoxInputList().get(i).getId()) {
							int quantity = state.getBoxInputList().get(i)
									.getQuantity()
									- simpleBlock.getBoxNumber();
							if (quantity > 0) {
								state.getBoxInputList().get(i)
										.setQuantity(quantity);
							} else {
								state.getBoxInputList().remove(i);
							}
						}
					}
				}
				for (int i = 0; i < state.getBoxInputList().size(); i++) {
					state.getBoxInputList().get(i).setId(i + 1);
				}
				lb = state.getBoxInputList();
				data.add(nodelist);
				data.add(bestState);
			}
		}
		long end_time = System.nanoTime();
		long minute = (long) ((end_time - start_time) / 1000000000.0) / 60;
		long second = (long) ((end_time - start_time) / 1000000000.0) % 60;
		System.out.println("รวมอัตราการใช้พื้นที่ทั้งหมด : "+(sumEvaluationScore / 4)+", และใช้เวลาไปทั้งหมด : "+minute+"."+second);
	}
}
